/**
 * @author a. lothore
 * @classDescription GUIApi object : API
 */
 
GUIApi.prototype = {};

//--------------------------------------------------------------------------------------------------------------------------
/*
* Constructor
*/
function GUIApi()
{
   this.autoLoad      	= GUIApi_autoLoad;
   this.manualLoad    	= GUIApi_manualLoad;
   this.getGG         	= GUIApi_getGG;
   this.getGGList     	= GUIApi_getGGList;
   this.log		      	= GUIApi_log;
   
   //List navigation
   this.getNext			= GUIApi_getNext;
   this.getPrevious		= GUIApi_getPrevious;
   this.getFirst		= GUIApi_getFirst;
   this.getLast			= GUIApi_getLast;  
   this.prepareView		= GUIApi_prepareView;
   
   //Not meant to be public
   this.getChildGUI           = GUIApi_getChildGUI;
   this.createGUIListFromDOM  = GUIApi_createGUIListFromDOM;
   this.loadChildren          = GUIApi_loadChildren;
}

//--------------------------------------------------------------------------------------------------------------------------
/*
* Automatically loads the content of a DOMObj
* @DOMObj : the root DOM object to parse and load
*/
function GUIApi_autoLoad(DOMObj)
{
  var listObj;
  
  if (DOMObj) 
    {listObj= $(".load_on_start",DOMObj);}
  else 
    {listObj = $(".load_on_start");}
  
  listObj.each(function (){
    GG.api.createGUIListFromDOM(this);
  });
}

//--------------------------------------------------------------------------------------------------------------------------
/* Loads a specific dataType child with the same DOM parent
 * TODO : handle multiple dataTypes input
 * TODO : Do it recursively ? (with N-depth ?)
 * @DOMObj : object to process
 * @dataType : dataType to search
 */
function GUIApi_manualLoad(DOMObj,dataType)
{	
  //Search for existing GUIList
  var objGUI = this.getChildGUI(DOMObj,dataType);
  
  if (!objGUI) 
  {
    //if no existing GUIList, it will be created
            
    //Searching for Datatypes to be loaded
    var parentGuiObj= $(DOMObj).parents("[guiid]").slice(0, 1);
    
    $("[dataObject='"+dataType+"']",parentGuiObj).each(function () {
      if (getNodeAttribute(this,"dataObject") == dataType)
      {
        var parentGUI = GG.api.getGG(this);
        GG.api.createGUIListFromDOM(this,parentGUI);
      }
    });
  }
  else
  {
    //If existing GUIList, it's a refresh
    objGUI.ready(function () {
    objGUI.goToView(getNodeAttribute(objGUI.getContainer(""),"defaultView"));}); 	       

    //SetTimeout to prevent browser freeze
    setTimeout(function() {objGUI.loadData();},0);
  }
}


//--------------------------------------------------------------------------------------------------------------------------
/* Automatically loads child dataTypes
 * @DOMObj : object to process
 */
function GUIApi_loadChildren(DOMObj)
{	
  var listObj;
  if (DOMObj) 
    {listObj= $(".load_on_parent",DOMObj);}
  listObj.each(function (){
    
    //Search for the first parent
    var parentGUIDOMObj = $(this).parents("[guiid]")[0];
    if (getNodeAttribute(parentGUIDOMObj,"guiid") == getNodeAttribute(DOMObj,"guiid")) 
    {
      var DOMObjGUI = this;
      var dataType = getNodeAttribute(DOMObjGUI,"dataObject");
      
      //Search for existing GUIList
      var objGUI = GG.api.getChildGUI(parentGUIDOMObj,dataType);
      
      if (!objGUI) 
      {
        var parentGUI = GG.api.getGG(parentGUIDOMObj);
        GG.api.createGUIListFromDOM(this,parentGUI);
      }
      else
      {
        //No automatic refresh, TODO ?
      }
    }
  });
}

//--------------------------------------------------------------------------------------------------------------------------
/* Creates a GuiList object from a DOM object, and loads it from db
 * TODO : handle multiple dataTypes input
 * @DOMObj : root DOM object to parse
 * @parentGui : parentGui to attach the new GUIlist to (optional)
 */
function GUIApi_createGUIListFromDOM(DOMObj,parentGui)
{
  var objGUIList = new GUIList();
  objGUIList.setObjectType(getNodeAttribute(DOMObj,"dataObject"));
  objGUIList.setDataSource(getNodeAttribute(DOMObj,"dataSource"));
  objGUIList.setApplicationId(getNodeAttribute(DOMObj,"applicationID"));
  objGUIList.setCallMethod(getNodeAttribute(DOMObj,"callMethod"));
  objGUIList.setUserShowFunction(stringToFunction(getNodeAttribute(DOMObj,"showFunction")));
  objGUIList.setUserHideFunction(stringToFunction(getNodeAttribute(DOMObj,"hideFunction")));
  objGUIList.attachToDOM(DOMObj); //TODO : Is it really useful ? With no pattern_DataType id, does nothing, but still works...
  
  if (parentGui) 
    {objGUIList.setParentGUI(parentGui);}
  
  //Looking for default view on DOM object
  objGUIList.ready(function () {
  objGUIList.goToView(getNodeAttribute(DOMObj,"defaultView"));}); 	          

  //SetTimeout to prevent browser freeze
  setTimeout(function() {objGUIList.loadData();},0);
  return objGUIList;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Find a specific child GUI(List) object for a DOMObject, given the DataType to find
 * Will match any GUIList having the same DataType in object_type list, or having "Any" DataType.
 * TODO : Will return last matching list, if it correct for multiple sublists of the same object type or having a "any" list ?
 * TODO2 : Handle no dataType / list without object_type ? ?
 * @DOMObj : object to process
 * @dataType : dataType to search
 */
function GUIApi_getChildGUI(DOMObj,dataType)
{
  var parentGUI = GG.api.getGG(DOMObj);
  var objGUI;
  
  //Search for existing GUIList
  applyOnGUIs(function(_this,GUIElem) {
                  if (GUIElem && GUIElem.parentGUI && GUIElem.parentGUI.client_id === parentGUI.client_id && (GUIElem.object_type === dataType || GUIElem.object_type === defaultSettings.untypedList || (GUIElem.object_type && GUIElem.object_type.indexOf(dataType)>=0))) 
                    {objGUI = GUIElem;}
              });
  return objGUI;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get the GUI object corresponding to a DOM object. The passed object can be a GUI object
 * //TODO : extend to a $-like selector ?
 * @obj : object to process
 */
function GUIApi_getGG(obj)
{
  if (obj)
  {
    if (obj.object_type)
      {return obj;}
    else
      {return htmlObjToGUI(obj);}
  }
  return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get the GUI object corresponding to a DOM object. The passed object can be a GUI object
 * //TODO : Refactor getGG to handle lists automatically ?
 * @obj : object to process
 */
function GUIApi_getGGList(obj)
{
  if (obj)
  {
    if (obj.isList)
      {return obj;}
    else
      {return htmlObjToGUIList(obj);}
  }
  return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Add log info
 * @text : log text
 * @logType : log type ("I" = info, "E" = Error)
 */
function GUIApi_log(text,logType)
{
  try {$.log(text,"I");}
  catch(e) {}
}

//--------------------------------------------------------------------------------------------------------------------------
/* Function used to convert a DOM object into its GUI Object equivalent
 * @DOMObj : the DOM object to convert
 */
function htmlObjToGUI(DOMObj)
{
	if (!DOMObj.guiid)
	{	
		if (DOMObj.parentNode)
			{return htmlObjToGUI(DOMObj.parentNode);}
		else
			{return null;}
	}
	if (DOMObj.guiid.value)
		{tempObj = getGUI(DOMObj.guiid.value);}
	else
		{tempObj = getGUI(DOMObj.guiid);}
	
	//Tests if it's not a list object
	if (!tempObj.isList)
		{return tempObj;}
	else
		{return htmlObjToGUI(DOMObj.parentNode);}
}

//--------------------------------------------------------------------------------------------------------------------------
/* Function used to convert a DOM object into its GUI list equivalent
 * @DOMObj : the DOM object to convert
 */
function htmlObjToGUIList(DOMObj)
{
	if (!DOMObj.guiid)
	{	
		if (DOMObj.parentNode)
			{return htmlObjToGUIList(DOMObj.parentNode);}
		else
			{return null;}
	}
	var tempObj;
	if (DOMObj.guiid.value)
		{tempObj = getGUI(DOMObj.guiid.value);}
	else
		{tempObj = getGUI(DOMObj.guiid);}
	
	//Tests if it's a list object
	if (tempObj.isList)
		{return tempObj;}
	else
		{return htmlObjToGUIList(DOMObj.parentNode);}
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get next object within list
 * @DOMObj : the DOM object to start from 
 */
function GUIApi_getNext(DOMObj)
{
	var dataObject = GG.api.getGG(DOMObj);
	if (dataObject && dataObject.parentList)
	{
		return dataObject.parentList.getNext(dataObject);
	}	
	return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get previous object within list
 * @DOMObj : the DOM object to start from 
 */
function GUIApi_getPrevious(DOMObj)
{
	var dataObject = GG.api.getGG(DOMObj);
	if (dataObject && dataObject.parentList)
	{
		return dataObject.parentList.getPrevious(dataObject);
	}	
	return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get the first object within list
 * @DOMObj : the DOM object to start from 
 */
function GUIApi_getFirst(DOMObj)
{
	var listObject = GG.api.getGGList(DOMObj);
	if (listObject)
	{
		return listObject.getFirst();
	}	
	return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Get the last object within list
 * @DOMObj : the DOM object to start from 
 */
function GUIApi_getLast(DOMObj)
{
	var listObject = GG.api.getGGList(DOMObj);
	if (listObject)
	{
		return listObject.getLast();
	}	
	return null;
}

//--------------------------------------------------------------------------------------------------------------------------
/* Prepare the specified view for an object (create DOM)
 * @obj : the DOM object to process (DOM object or GUI object)
 * @viewName : the view name to display
 */
function GUIApi_prepareView(obj, viewName)
{
	var dataObject = GG.api.getGG(obj);
	if (dataObject)
	{
		return dataObject.getView(viewName);
	}	
	return null;
}
